﻿const Rule = require('./rule');
const logger = require('../logs/logger');
const url = require('url');
const qs = require('querystring');
const fs = require('fs');
const injector = require('../injector/injector');
const brandSvr = require('../svrs/brandSvr');
const moment = require('moment');

// privates 

const metaJs = `<script>${fs.readFileSync('injector/meta.js', 'utf-8')}</script>`;

_args = {};

function isGetMsgExt(req, resp) {
    return req.url.indexOf('mp.weixin.qq.com/mp/getappmsgext?') > -1 && req.requestOptions.method === 'POST';
}

function isLoadMsg(req, resp) {
    return req.url.indexOf('mp.weixin.qq.com/s?') > -1 && req.requestOptions.method === 'GET';
}

// privates 

class ArticleRule extends Rule {
    constructor(args) { super(args); _args = args; }

    get name() { return 'article rule'; }

    get enable() { return true; }

    isMatch(req, resp) {
        if (req && resp) {
            return isGetMsgExt(req, resp) || isLoadMsg(req, resp);
        }
        return false;
    }

    execute(req, resp) {
        var response = resp.response;
        var headers = req.requestOptions.headers;

        if (isGetMsgExt(req, resp)) {
            var q = qs.parse(url.parse(headers['Referer']).query);
            var stat = JSON.parse(resp.response.body).appmsgstat;

            var msg = {
                biz: q.__biz instanceof Array ? q.__biz[0] : q.__biz,
                mid: q.mid,
                idx: q.idx,
                reads: stat ? stat.read_num : 0,
                likes: stat ? stat.like_num : 0,
                updateAt: moment(new Date()).valueOf()
            };
            _args.mq.send('msgext', JSON.stringify(msg));
        }

        if (isLoadMsg(req, resp)) {
            let header = Object.assign({}, response.header);
            delete header['Content-Security-Policy'];
            delete header['Content-Security-Policy-Report-Only'];
            header['Expires'] = 0;
            header['Cache-Control'] = 'no-cache, no-store, must-revalidate';
            response.header = header;

            let cQs = qs.parse(url.parse(req.url).query);

            var next = _args.mgr.popMsg(cQs.__biz);

            while (next && next.src.trim() === '') {
                next = _args.mgr.popMsg(cQs.__biz);
            }

            if (next && next.src) {
                let nQs = qs.parse(url.parse(next.src).query);

                while (next && next.src.trim() !== '' && cQs.__biz === nQs.__biz && cQs.mid === nQs.mid && cQs.idx === nQs.idx) {
                    next = _args.mgr.popMsg(cQs.__biz);
                    nQs = qs.parse(url.parse(next.src).query);
                }

                var delay = Math.floor(Math.random() * 5 + 3) * 1000;
                response.body = injector.inject(response.body,
                    metaJs.replace('$__delay', delay)
                        .replace(/\$__next/g, next.src.replace(/amp;/g, '')),
                );
            } else {
                brandSvr.single(cQs.__biz, r => {
                    _args.hub.then(connection => {
                        connection.invoke('CompleteSubscription', r.nick).catch(console.error);
                    })
                        .catch(console.error);
                });
            }
        }
    }
}

module.exports = ArticleRule;